package com.fin.zw.aiqas.service;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.bean.copier.CopyOptions;
import com.fin.zw.aiqas.entity.*;
import com.fin.zw.aiqas.mapper.RuleStatisticsMapper;
import com.fin.zw.aiqas.model.data.InspectionDetailModel;
import com.fin.zw.aiqas.model.request.InspectionDetailQueryRequest;
import com.fin.zw.aiqas.model.request.InspectionDetailRequest;
import com.fin.zw.aiqas.model.request.RuleHistRequest;
import com.fin.zw.aiqas.model.response.DepartmentResponse;
import com.fin.zw.aiqas.model.response.InspectionDetailQueryResponse;
import com.fin.zw.aiqas.model.session.SessionModel;
import com.fin.zw.aiqas.repository.InspectionDetailRepository;
import com.fin.zw.aiqas.repository.UserInfoRepository;
import com.fin.zw.aiqas.util.BadRequestException;
import com.fin.zw.aiqas.util.CSVUtils;
import com.querydsl.core.BooleanBuilder;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Pageable;
import org.springframework.data.domain.Sort;
import org.springframework.stereotype.Service;

import javax.validation.constraints.NotNull;
import java.io.File;
import java.text.SimpleDateFormat;
import java.util.*;

@Service("inspectionDetailService")
public class InspectionDetailService {
    private final static Logger log = LoggerFactory.getLogger(InspectionDetailService.class);

    @Autowired
    InspectionDetailRepository inspectionDetailRepository;

    @Autowired
    private RuleStatisticsMapper ruleStatisticsMapper;

    @Autowired
    private UserInfoRepository userInfoRepository;

    @Value("${file.filepath}")
    private String filepath;

    /**
     * 修改质检结果详情信息
     *
     * @param request 质检结果详情
     * @param session 操作的用户信息
     */
    public void updateInspectionDetail(InspectionDetailRequest request, SessionModel session) throws RuntimeException {
        if (request.getId() == null) throw new BadRequestException("", "需要修改的数据不存在！！！！");
        InspectionDetail detail = getInspectionDetail(request);
        inspectionDetailRepository.save(detail);
    }

    @NotNull
    private InspectionDetail getInspectionDetail(InspectionDetailRequest request) {
        InspectionDetail detail = new InspectionDetail();
        Department department = new Department();
        BeanUtil.copyProperties(request, detail);
        detail.setDepartment(department);
        department.setId(request.getDepartment().getId());
        department.setName(request.getDepartment().getName());
        department.setCode(request.getDepartment().getCode());
        return detail;
    }



    /**
     * 质检结果详情
     * @param request  条件参数
     * @param pageable 分页参数
     * @return 返回结果对象
     */
   /* public Page<InspectionDetailQueryResponse> queryInspectionDetailById(InspectionDetailQueryRequest request, Pageable pageable) {
        BooleanBuilder builder = builderSQL(request);
        Page<InspectionDetail> detailPage = inspectionDetailRepository.findAll(builder, pageable);
        Page<InspectionDetailQueryResponse> page = detailPage.map(tt -> {
            InspectionDetailQueryResponse response = new InspectionDetailQueryResponse();
            DepartmentResponse departmentResponse = new DepartmentResponse();
            BeanUtil.copyProperties(tt, response, true, CopyOptions.create().setIgnoreNullValue(true).setIgnoreError(true));
            BeanUtil.copyProperties(tt.getDepartment(), departmentResponse, true, CopyOptions.create().setIgnoreNullValue(true).setIgnoreError(true));
            if (tt.getDepartment() != null && tt.getDepartment().getParent() != null) {
                departmentResponse.setParent(tt.getDepartment().getParent().getId());
            }
            response.setDepartment(departmentResponse);
            return response;
        });
        return page;
    }*/

    /**
     * 质检结果详情
     * @param request  条件参数
     * @param pageable 分页参数
     * @return 返回结果对象
     */
    public Page<InspectionDetailQueryResponse> queryInspectionDetailById(InspectionDetailQueryRequest request, Pageable pageable) {
        BooleanBuilder builder = builderSQL(request);
        Sort sort = new Sort(Sort.Direction.DESC, "runDate");
        int pageSize = pageable.getPageSize();
        int pageNumber = pageable.getPageNumber();
        Pageable pageable1 = new PageRequest(pageNumber, pageSize, sort);
        Page<InspectionDetail> detailPage = inspectionDetailRepository.findAll(builder, pageable1);
        Page<InspectionDetailQueryResponse> page = detailPage.map(tt -> {
            InspectionDetailQueryResponse response = new InspectionDetailQueryResponse();
            DepartmentResponse departmentResponse = new DepartmentResponse();
            BeanUtil.copyProperties(tt, response, true, CopyOptions.create().setIgnoreNullValue(true).setIgnoreError(true));
            BeanUtil.copyProperties(tt.getDepartment(), departmentResponse, true, CopyOptions.create().setIgnoreNullValue(true).setIgnoreError(true));
            if (tt.getDepartment() != null && tt.getDepartment().getParent() != null) {
                departmentResponse.setParent(tt.getDepartment().getParent().getId());
            } else {
                //如果没有部门就从分机号去查询人员对应的部门
                if (StringUtils.isNotBlank(tt.getServiceExt())) {
                    Optional<UserInfo> optional = userInfoRepository.findOne(QUserInfo.userInfo.extNumber.eq(tt.getServiceExt()));
                    if (optional.isPresent()) {
                        UserInfo userInfo = optional.get();
                        Department department = userInfo.getDepartment();
                        com.fin.zw.aiqas.util.BeanUtil.copyProperties(department, departmentResponse);
                    }
                }
            }
            //客服名称
            if (StringUtils.isNotBlank(tt.getServiceExt())) {
                Optional<UserInfo> one = userInfoRepository.findOne(QUserInfo.userInfo.extNumber.eq(tt.getServiceExt()));
                if (one.isPresent()) {
                    response.setServiceName(one.get().getName());
                }
            }
            response.setDepartment(departmentResponse);
            return response;
        });
        return page;
    }


    /**
     * 根据规则id查询命中的结果
     *
     * @param request
     * @return
     */
    public List<InspectionDetailModel> queryInspectionDetailModelByRuleId(RuleHistRequest request) {
        return ruleStatisticsMapper.selectInspectionDetailByRuleId(request);
    }
    public Integer queryCountInspectionDetailModelByRuleId(RuleHistRequest request) {
        return ruleStatisticsMapper.selectCountInspectionDetailByRuleId(request);
    }

    /**
     * 根据ID查新明细
     *
     * @param id
     * @return
     */
    public InspectionDetail findById(Long id) {
        return inspectionDetailRepository.findById(id).orElseThrow(() -> new BadRequestException("", "没有 ID 为 " + id + " 的结果明细"));
    }

    /**
     * 根据ID查新明细
     *
     * @param id
     * @return
     */
    public InspectionDetailQueryResponse queryDetailById(Long id) {
        InspectionDetail inspectionDetail = inspectionDetailRepository.findById(id).orElseThrow(() -> new BadRequestException("", "没有 ID 为 " + id + " 的结果明细"));
        InspectionDetailQueryResponse response = new InspectionDetailQueryResponse();
        BeanUtils.copyProperties(inspectionDetail, response);
        return response;
    }

    /**
     * 导出数据
     *
     * @param request
     * @return
     */
    public File exportFile(InspectionDetailQueryRequest request) {
        LinkedHashMap<String, String> headMap = new LinkedHashMap<>();
        headMap.put("taskName", "任务名称");
        headMap.put("serviceCode", "客服编号");
        headMap.put("serviceExt", "分机号码");
        headMap.put("customerPhone", "被叫号码");
        headMap.put("fileName", "文件名");
        headMap.put("department", "部门");
        headMap.put("qualityStatus", "质检状态");
        headMap.put("hitRule", "命中规则");
        headMap.put("hitStatus", "命中结果");
        headMap.put("voiceLength", "录音时长");
        headMap.put("runDate", "质检时间");
        headMap.put("reviewDate", "复核时间");
        headMap.put("reviewUserInfo", "复核人员");
        headMap.put("reviewContent", "复核备注");
        headMap.put("applyTime", "复议申请时间");
        headMap.put("reconsiderDate", "复议审批时间");
        headMap.put("reconsiderUserInfo", "复议审批人员");
        headMap.put("reasons", "复议申请原因");
        headMap.put("opinion", "复议审批意见");
        List<LinkedHashMap> exportData = new ArrayList<>();
        BooleanBuilder builder = builderSQL(request);
        Iterator<InspectionDetail> inspectionDetails = inspectionDetailRepository.findAll(builder, new Sort(Sort.Direction.DESC, "runDate")).iterator();
        LinkedHashMap<String, String> bean = null;
        while (inspectionDetails.hasNext()) {
            bean = new LinkedHashMap<>();
            InspectionDetail inspectionDetail = inspectionDetails.next();
            bean.put("taskName", (Objects.isNull(inspectionDetail.getTaskInfo())) ? "" : inspectionDetail.getTaskInfo().getName());
            bean.put("serviceCode", inspectionDetail.getServiceCode());
            bean.put("serviceExt", (Objects.isNull(inspectionDetail.getServiceExt())) ? "" : inspectionDetail.getServiceExt());
            bean.put("customerPhone", (Objects.isNull(inspectionDetail.getCustomerPhone())) ? "" : inspectionDetail.getCustomerPhone());
            bean.put("fileName", (Objects.isNull(inspectionDetail.getFileName())) ? "" : inspectionDetail.getFileName());
            if (Objects.isNull(inspectionDetail.getDepartment())) {
                //如果没有部门就从分机号去查询人员对应的部门
                if (StringUtils.isNotBlank(inspectionDetail.getServiceExt())) {
                    Optional<UserInfo> optional = userInfoRepository.findOne(QUserInfo.userInfo.extNumber.eq(inspectionDetail.getServiceExt()));
                    if (optional.isPresent()) {
                        UserInfo userInfo = optional.get();
                        bean.put("department", userInfo.getDepartment().getName());
                    } else {
                        bean.put("department", "");
                    }
                }
            } else {
                bean.put("department", inspectionDetail.getDepartment().getName());
            }
            //质检状态
            switch (inspectionDetail.getQualityStatus()) {
                case READY:
                    bean.put("qualityStatus", "就绪");
                    break;
                case QUALITYING:
                    bean.put("qualityStatus", "语音质检中");
                    break;
                case FINISH:
                    bean.put("qualityStatus", "质检完成");
                    break;
            }
            bean.put("hitRule", inspectionDetail.getHitRule());
            //命中结果
            switch (inspectionDetail.getHitStatus()) {
                case INIT:
                    bean.put("hitStatus", "初始化");
                    break;
                case HIT:
                    bean.put("hitStatus", "命中");
                    break;
                case MISS:
                    bean.put("hitStatus", "未命中");
                    break;
            }
            bean.put("voiceLength", (inspectionDetail.getVoiceLength() == null) ? "" : String.valueOf(inspectionDetail.getVoiceLength()));
            bean.put("runDate", (inspectionDetail.getRunDate() == null) ? "" : new SimpleDateFormat("yyyy/MM/dd").format(inspectionDetail.getRunDate()));
            bean.put("reviewDate", (inspectionDetail.getReviewDate() == null) ? "" : new SimpleDateFormat("yyyy/MM/dd").format(inspectionDetail.getReviewDate()));
            bean.put("reviewUserInfo", (Objects.isNull(inspectionDetail.getReviewUserInfo())) ? "" : inspectionDetail.getReviewUserInfo().getName());
            bean.put("reviewContent", inspectionDetail.getReviewContent());
            bean.put("applyTime", (inspectionDetail.getApplyTime() == null) ? "" : new SimpleDateFormat("yyyy/MM/dd").format(inspectionDetail.getApplyTime()));
            bean.put("reconsiderDate", (inspectionDetail.getReconsiderDate() == null) ? "" : new SimpleDateFormat("yyyy/MM/dd").format(inspectionDetail.getReconsiderDate()));
            bean.put("reconsiderUserInfo", (Objects.isNull(inspectionDetail.getReconsiderUserInfo())) ? "" : inspectionDetail.getReconsiderUserInfo().getName());
            bean.put("reasons", inspectionDetail.getReasons());
            bean.put("opinion", inspectionDetail.getOpinion());
            exportData.add(bean);
        }
        return CSVUtils.createCSVFile(exportData, headMap, filepath, "Download");
    }

    /**
     * 公共的sql拼接方法
     *
     * @param request
     * @return
     */
    private BooleanBuilder builderSQL(InspectionDetailQueryRequest request) {
        BooleanBuilder builder = new BooleanBuilder();
        QInspectionDetail qDetail = QInspectionDetail.inspectionDetail;
        if (request.getInspectionId() != null) {
            builder.and(qDetail.inspectionInfo.id.eq(request.getInspectionId()));
        }
        //客服编号
        if (StringUtils.isNotEmpty(request.getServiceCode())) {
            builder.and(qDetail.serviceCode.eq(request.getServiceCode()));
        }
        //分机号
        if (StringUtils.isNotEmpty(request.getServiceExt())) {
            builder.and(qDetail.serviceExt.eq(request.getServiceExt()));
        }
        //部门
        if (null != request.getDepartId()) {
            builder.and(qDetail.department.id.eq(request.getDepartId()));
        }
        //质检状态
        if (request.getQualityStatus() != null) {
            builder.and(qDetail.qualityStatus.eq(request.getQualityStatus()));
        }
        //命中结果
        if (request.getHitStatus() != null) {
            builder.and(qDetail.hitStatus.eq(request.getHitStatus()));
        }
        //质检开始时间和结束时间
        if (null != request.getRunStartTime() && null != request.getRunEndTime()) {
            builder.and(qDetail.runDate.between(request.getRunStartTime(), request.getRunEndTime()));
        }
        //复合人员
        if (StringUtils.isNotEmpty(request.getReviewUserName())) {
            builder.and(qDetail.reviewUserInfo.name.like("%".concat(request.getReviewUserName()).concat("%")));
        }
        //复议人员
        if (StringUtils.isNotEmpty(request.getReconsiderationUserName())) {
            builder.and(qDetail.reconsiderUserInfo.name.like("%".concat(request.getReconsiderationUserName()).concat("%")));
        }
        //任务名称
        if (request.getTaskId() != null) {
            builder.and(qDetail.taskInfo.id.eq(request.getTaskId()));
        }
        //任务批次
        if (StringUtils.isNotEmpty(request.getTaskBatch())) {
            builder.and(qDetail.inspectionInfo.inspectionBatch.like("%".concat(request.getTaskBatch()).concat("%")));
        }
        //文件名
        if (StringUtils.isNotBlank(request.getFileName())) {
            builder.and(qDetail.fileName.like("%".concat(request.getFileName()).concat("%")));
        }
        //规则
        if (StringUtils.isNotBlank(request.getHitRule())) {
            builder.and(qDetail.hitRule.like("%".concat(request.getHitRule()).concat("%")));
        }
        return builder;
    }

}
